import gameConfig from "../../engines/configs/gameConfig";
import O1HD, { managers, services } from "../../engines/gameEngine";
import { GAME_MODE } from "../../engines/managers/gameContent/gameMode_json";
import localStorageService from "../../engines/services/localStorageService";
import { REWARD_TYPE } from "../../engines/services/userContent/userInterface";
import NormalLevelBase from "../Base/LevelBase";
import SystemBase from "../Base/SystemBase";
import { MODE_NAME_MAP } from "../Const";
import { PAGE } from "../Enum";
import {
    IGameModeMap,
    IGameModeContent,
    INormalLevelStruct,
    ILevelMap,
    ILevelInfo,
} from "../Interface";

import mainRoot from "../MainRoot";

export default class LevelSystem extends SystemBase {
    systemName: string = "===主模式关卡系统";

    public get GameBundle() {
        return cc.assetManager.getBundle("gameBundle");
    }

    private readonly level_Save_Content: string = "level_Save_Content"; // 所有模式的关卡信息存储键值
    private m_levelContent: IGameModeMap = null;

    /** 默认模式 */
    private m_normalLevelMap: ILevelMap = <ILevelMap>{};
    /** 最新关卡模式 */
    private m_newwestLevelMap: ILevelMap = <ILevelMap>{};
    /** 神奇汉子 */
    private m_shenqiLevelMap: ILevelMap = <ILevelMap>{};
    /** 玩梗消除 */
    private m_wangengLevelMap: ILevelMap = <ILevelMap>{};
    /** 连线达人 */
    private m_lianxianLevelMap: ILevelMap = <ILevelMap>{};

    //TODO 新模式请看这里
    /**
     * 获取关卡信息
     * @param mode 关卡属于的模式
     * @param levelNum 关卡数，默认为模式当前关卡
     * @returns
     */
    public GetSignleLevelInfo(mode: GAME_MODE, levelNum?: number) {
        if (!levelNum) {
            levelNum = this.GetCurrLevel(mode);
        }
        // else if (mode == 3) {
        //     levelNum = this.GetShenqiLevel(mode);
        // }
        // else if (mode == 4) {
        //     levelNum = this.GetWangengLevel(mode);
        // }
        // else if (mode == 5) {
        //     levelNum = this.GetLianxianLevel(mode);
        // }
        switch (mode) {
            case GAME_MODE.NORMAL:
                return this.m_normalLevelMap[this.realNum(levelNum, mode)];
            case GAME_MODE.CARD_COMPOSITION:
                return this.m_newwestLevelMap[this.realNum(levelNum, mode)];
            case GAME_MODE.SHENQIHANZI:
                return this.m_shenqiLevelMap[this.realNum(levelNum, mode)];
            case GAME_MODE.WANGENG:
                return this.m_wangengLevelMap[this.realNum(levelNum, mode)];
            case GAME_MODE.LIANXIAN:
                return this.m_lianxianLevelMap[this.realNum(levelNum, mode)];
        }
        //TODO 新模式请看这里
    }

    public GetModeLevelInfo(mode: GAME_MODE) {
        switch (mode) {
            case GAME_MODE.NORMAL:
                return this.m_normalLevelMap;
            case GAME_MODE.CARD_COMPOSITION:
                return this.m_newwestLevelMap;
            case GAME_MODE.SHENQIHANZI:
                return this.m_shenqiLevelMap;
            case GAME_MODE.WANGENG:
                return this.m_wangengLevelMap;
            case GAME_MODE.LIANXIAN:
                return this.m_lianxianLevelMap;
        }
        //TODO 新模式请看这里
    }

    realNum(levelNum, mode: GAME_MODE) {
        let realLevelNum = levelNum % this.m_levelContent[mode].maxLevel;
        if (!realLevelNum) {
            realLevelNum = this.m_levelContent[mode].maxLevel;
        }
        if (realLevelNum > this.m_levelContent[mode].maxLevel) {
            realLevelNum = 1;
        }
        // console.warn(this.m_levelContent[mode].maxLevel, realLevelNum);
        return realLevelNum;
    }

    public GetFarLevel(mode: GAME_MODE) {
        return this.m_levelContent[mode].farLevel || 1;
    }
    public GetNewwestLevel(mode: GAME_MODE) {
        return this.m_levelContent[mode].newwestLevel || 1;
    }
    public GetShenqiLevel(mode: GAME_MODE) {
        return this.m_levelContent[mode].shenqiLevel || 1;
    }
    public GetWangengLevel(mode: GAME_MODE) {
        return this.m_levelContent[mode].wangengLevel || 1;
    }
    public GetLianxianLevel(mode: GAME_MODE) {
        return this.m_levelContent[mode].lianxianLevel || 1;
    }
    public GetCurrLevel(mode: GAME_MODE) {
        return this.m_levelContent[mode].currLevel || 1;
    }
    public GetMaxLevel(mode: GAME_MODE) {
        return this.m_levelContent[mode].maxLevel || 1;
    }
    public GetUnlockLevel(mode: GAME_MODE) {
        return this.m_levelContent[mode].unlockLevleList || [1];
    }

    public needUnlock: boolean = false; // 是否需要播放关卡解锁动画

    private stroage: localStorageService = null;

    SystemInit(...pram: any) {
        super.SystemInit();
        this.stroage = O1HD.getServices().localStorageSrv;
        this.m_levelContent = {
            0: <IGameModeContent>{ currLevel: 1, farLevel: 1, unlockLevleList: [1] },
            1: <IGameModeContent>{ currLevel: 1, farLevel: 1, unlockLevleList: [1] },
            3: <IGameModeContent>{ currLevel: 1, farLevel: 1, unlockLevleList: [1] },
            4: <IGameModeContent>{ currLevel: 1, farLevel: 1, unlockLevleList: [1] },
            5: <IGameModeContent>{ currLevel: 1, farLevel: 1, unlockLevleList: [1] },
            6: <IGameModeContent>{ currLevel: 1, farLevel: 1, unlockLevleList: [1] },
            7: <IGameModeContent>{ currLevel: 1, farLevel: 1, unlockLevleList: [1] },
            8: <IGameModeContent>{ currLevel: 1, farLevel: 1, unlockLevleList: [1] },
        };
        //TODO 新模式请看这里
        let init = (config: ILevelInfo[], map: ILevelMap) => {
            for (let index = 0; index < config.length; index++) {
                const element = config[index];
                map[element.id] = element.content;
            }
        };
        let initNewwest = (config: ILevelInfo[], map: ILevelMap) => {
            for (let index = 0; index < config.length; index++) {
                const element = config[index];
                map[element.id] = element.content;
            }
        };
        let initShenQi = (config: ILevelInfo[], map: ILevelMap) => {
            for (let index = 0; index < config.length; index++) {
                const element = config[index];
                map[element.id] = element.content;
            }
        };
        let initWanGeng = (config: ILevelInfo[], map: ILevelMap) => {
            for (let index = 0; index < config.length; index++) {
                const element = config[index];
                map[element.id] = element.content;
            }
        };
        let initLianXian = (config: ILevelInfo[], map: ILevelMap) => {
            for (let index = 0; index < config.length; index++) {
                const element = config[index];
                map[element.id] = element.content;
            }
        };


        // NOTE 添加模式需要修改的地方
        init(mainRoot.ConfigSerive.NormalLevelList, this.m_normalLevelMap);
        initNewwest(mainRoot.ConfigSerive.NewestLevelList, this.m_newwestLevelMap);
        initShenQi(mainRoot.ConfigSerive.ShenqiLevelList, this.m_shenqiLevelMap);
        initWanGeng(mainRoot.ConfigSerive.WanGengLevelList, this.m_wangengLevelMap);
        initLianXian(mainRoot.ConfigSerive.LianXianLevelList, this.m_lianxianLevelMap);

        //TODO 新模式请看这里
        let allContent: string = this.stroage.getStorage(this.level_Save_Content);
        if (allContent) {
            let object = JSON.parse(allContent);
            for (const key in object) {
                if (Object.prototype.hasOwnProperty.call(object, key)) {
                    const element = object[key];
                    this.m_levelContent[key] = element;
                }
            }
            // this.m_levelContent = JSON.parse(allContent);
        }

        /** 配置默认表 */
        let array = mainRoot.ConfigSerive.LevelSourceList;
        for (let index = 0; index < array.length; index++) {
            const element = array[index];

            let levelSource = mainRoot.ConfigSerive[element.responName];
            // this.m_levelContent[element.name] = <IGameModeContent>{};
            this.m_levelContent[element.mode].maxLevel = levelSource.length; // 获取配置服务中的特定配置表的长度
            this.m_levelContent[element.mode].farLevel = Math.min(
                levelSource.length,
                this.m_levelContent[element.mode].farLevel
            );
            this.m_levelContent[element.mode].currLevel = Math.min(
                levelSource.length,
                this.m_levelContent[element.mode].currLevel
            );
            this.m_levelContent[element.mode].unlockLevleList =
                this.m_levelContent[element.mode].unlockLevleList;
            if (
                this.m_levelContent[element.mode].unlockLevleList == null ||
                this.m_levelContent[element.mode].unlockLevleList == undefined
            ) {
                //兼容线上
                this.m_levelContent[element.mode].unlockLevleList = [];
                for (
                    let i: number = 1;
                    i <= this.m_levelContent[element.mode].farLevel;
                    i++
                ) {
                    this.m_levelContent[element.mode].unlockLevleList.push(i);
                }
                this.OnLevelChange();
            }
        }

        /** 配置最新关卡表 */
        let arrayNewest = mainRoot.ConfigSerive.NewestMSLevelSourceList;
        for (let index = 0; index < arrayNewest.length; index++) {
            const element = arrayNewest[index];

            let levelSource = mainRoot.ConfigSerive[element.responName];
            // this.m_levelContent[element.name] = <IGameModeContent>{};
            this.m_levelContent[element.mode].maxLevel = levelSource.length; // 获取配置服务中的特定配置表的长度
            this.m_levelContent[element.mode].farLevel = Math.min(
                levelSource.length,
                this.m_levelContent[element.mode].farLevel
            );
            this.m_levelContent[element.mode].currLevel = Math.min(
                levelSource.length,
                this.m_levelContent[element.mode].currLevel
            );
            this.m_levelContent[element.mode].unlockLevleList =
                this.m_levelContent[element.mode].unlockLevleList;
            if (
                this.m_levelContent[element.mode].unlockLevleList == null ||
                this.m_levelContent[element.mode].unlockLevleList == undefined
            ) {
                //兼容线上
                this.m_levelContent[element.mode].unlockLevleList = [];
                for (
                    let i: number = 1;
                    i <= this.m_levelContent[element.mode].farLevel;
                    i++
                ) {
                    this.m_levelContent[element.mode].unlockLevleList.push(i);
                }
                this.OnLevelChange();
            }
        }

        /** 配置神奇汉字表 */
        let arrayShenQi = mainRoot.ConfigSerive.ShenqiMSLevelSourceList;
        for (let index = 0; index < arrayShenQi.length; index++) {
            const element = arrayShenQi[index];

            let levelSource = mainRoot.ConfigSerive[element.responName];
            // this.m_levelContent[element.name] = <IGameModeContent>{};
            this.m_levelContent[element.mode].maxLevel = levelSource.length; // 获取配置服务中的特定配置表的长度
            this.m_levelContent[element.mode].farLevel = Math.min(
                levelSource.length,
                this.m_levelContent[element.mode].farLevel
            );
            this.m_levelContent[element.mode].currLevel = Math.min(
                levelSource.length,
                this.m_levelContent[element.mode].currLevel
            );
            this.m_levelContent[element.mode].unlockLevleList =
                this.m_levelContent[element.mode].unlockLevleList;
            if (
                this.m_levelContent[element.mode].unlockLevleList == null ||
                this.m_levelContent[element.mode].unlockLevleList == undefined
            ) {
                //兼容线上
                this.m_levelContent[element.mode].unlockLevleList = [];
                for (
                    let i: number = 1;
                    i <= this.m_levelContent[element.mode].farLevel;
                    i++
                ) {
                    this.m_levelContent[element.mode].unlockLevleList.push(i);
                }
                this.OnLevelChange();
            }
        }

        /** 配置玩梗消除表 */
        let arrayWanGeng = mainRoot.ConfigSerive.WangengMSLevelSourceList;
        for (let index = 0; index < arrayWanGeng.length; index++) {
            const element = arrayWanGeng[index];

            let levelSource = mainRoot.ConfigSerive[element.responName];
            // this.m_levelContent[element.name] = <IGameModeContent>{};
            this.m_levelContent[element.mode].maxLevel = levelSource.length; // 获取配置服务中的特定配置表的长度
            this.m_levelContent[element.mode].farLevel = Math.min(
                levelSource.length,
                this.m_levelContent[element.mode].farLevel
            );
            this.m_levelContent[element.mode].currLevel = Math.min(
                levelSource.length,
                this.m_levelContent[element.mode].currLevel
            );
            this.m_levelContent[element.mode].unlockLevleList =
                this.m_levelContent[element.mode].unlockLevleList;
            if (
                this.m_levelContent[element.mode].unlockLevleList == null ||
                this.m_levelContent[element.mode].unlockLevleList == undefined
            ) {
                //兼容线上
                this.m_levelContent[element.mode].unlockLevleList = [];
                for (
                    let i: number = 1;
                    i <= this.m_levelContent[element.mode].farLevel;
                    i++
                ) {
                    this.m_levelContent[element.mode].unlockLevleList.push(i);
                }
                this.OnLevelChange();
            }
        }
        let arrayLianXian = mainRoot.ConfigSerive.LianxianMSLevelSourceList;
        for (let index = 0; index < arrayLianXian.length; index++) {
            const element = arrayLianXian[index];

            let levelSource = mainRoot.ConfigSerive[element.responName];
            // this.m_levelContent[element.name] = <IGameModeContent>{};
            this.m_levelContent[element.mode].maxLevel = levelSource.length; // 获取配置服务中的特定配置表的长度
            this.m_levelContent[element.mode].farLevel = Math.min(
                levelSource.length,
                this.m_levelContent[element.mode].farLevel
            );
            this.m_levelContent[element.mode].currLevel = Math.min(
                levelSource.length,
                this.m_levelContent[element.mode].currLevel
            );
            this.m_levelContent[element.mode].unlockLevleList =
                this.m_levelContent[element.mode].unlockLevleList;
            if (
                this.m_levelContent[element.mode].unlockLevleList == null ||
                this.m_levelContent[element.mode].unlockLevleList == undefined
            ) {
                //兼容线上
                this.m_levelContent[element.mode].unlockLevleList = [];
                for (
                    let i: number = 1;
                    i <= this.m_levelContent[element.mode].farLevel;
                    i++
                ) {
                    this.m_levelContent[element.mode].unlockLevleList.push(i);
                }
                this.OnLevelChange();
            }
        }

        // this.Log(this.m_levelContent);
    }

    /**
     * 变换大关卡,大关卡变换时仅可调用此接口
     * @param levelNum 大关卡数
     * @param mode 游戏模式
     */
    ChangeLevel(levelNum: number, mode: GAME_MODE) {
        this.m_levelContent[mode].currLevel = levelNum;
        this.m_levelContent[mode].farLevel = Math.max(
            levelNum,
            this.m_levelContent[mode].farLevel
        );
        this.m_levelContent[mode].farLevel = Math.min(
            this.m_levelContent[mode].maxLevel,
            this.m_levelContent[mode].farLevel
        );
        if (this.m_levelContent[mode].unlockLevleList.indexOf(levelNum) < 0) {
            this.m_levelContent[mode].unlockLevleList.push(levelNum);
        }
        this.m_levelContent[mode].unlockLevleList.sort((a: number, b: number) => {
            return a - b;
        });
        this.OnLevelChange();
    }

    getIsUnLockAll()
    {
        let have:boolean=false;
        for (let m = 0; m < GAME_MODE.LIANXIAN; m ++) {
            if(this.m_levelContent[m]) {
                for(let i=0;i<this.m_levelContent[m].maxLevel+1;i++)
                {
                    if (this.m_levelContent[m].unlockLevleList.indexOf(i) < 0) {
                        have=true
                    }
                }
            }
        }

        return have
    }
    
    unAllLock( mode: GAME_MODE) {
        // for(let m=0;m<GAME_MODE.LIANXIAN;m++)
        // {
        //     if(this.m_levelContent[m])
        //     {
        //         for(let i=0;i<this.m_levelContent[m].maxLevel+1;i++)
        //         {
                    
        //             if (this.m_levelContent[m].unlockLevleList.indexOf(i) < 0) {
        //                 this.m_levelContent[m].unlockLevleList.push(i);
        //             }
        //         }
        //         this.m_levelContent[m].unlockLevleList.sort((a: number, b: number) => {
        //             return a - b;
        //         });
        //     }
        // }
        // this.OnLevelChange();
        O1HD.getServices().userSrv.setLevelAllUnlockTime();
        O1HD.getServices().userSrv.setLevelAllUnlockFlag(true);

    }

    OnLevelChange(): boolean {
        this.stroage.setStorage(
            this.level_Save_Content,
            JSON.stringify(this.m_levelContent)
        );
        return true;
    }

    currentContent:INormalLevelStruct = null;

    get CurrentContent(){
        return this.currentContent;
    }

    /**
     * 增加关卡计数
     */
    AddLevel(mode: GAME_MODE, num: number = 1) {
        console.warn("关卡加1", mode);
        this.ChangeLevel(this.m_levelContent[mode].currLevel + num, mode);
    }
    /**
     * 加载关卡
     * @param bundleName 关卡所在的分包名
     * @param levelNum 关卡数
     */
    async LoadLevel(bundleName: string, mode: GAME_MODE, levelNum?: number,isShowLoading:boolean = true,infinityInfo:INormalLevelStruct = null) {
        if (!levelNum) {
            levelNum = this.GetCurrLevel(mode);
        }
        // mainRoot.UISystem.CloseAllPage();
        // mainRoot.GotTips = false;
        // if(O1HD.getServices().userSrv.getPower()-gameConfig.MODE_POWER[mode]<0){
        //     mainRoot.UIModel.showUserPropGet(REWARD_TYPE.POWER,gameConfig.ADD_ONCE_POWER);
        //     return;
        // }
        // services()
        //     .miniGameSrv.getAppApiInstance()
        //     .gameRecordStart({ duration: 180 });
        // console.warn("输入", levelNum, "包名", bundleName);
        let realNum = this.realNum(levelNum, mode);
        this.ChangeLevel(realNum, mode);
        // console.warn("加载", realNum);
        let content: INormalLevelStruct = this.GetSignleLevelInfo(mode, realNum);
        this.currentContent = content;
        let sceneMode = mode;
        //mode 加载的包名 如果填写 会直接强制去load mode Id 所指向的bundleName 方便各游戏穿插调佣
        if (content.mode !== undefined && content.mode !== null) {
            sceneMode = content.mode;
            // console.log("?????", sceneMode);
        }

        if(infinityInfo){
            content = infinityInfo;
        }

        const prams: INormalLevelStruct = {
            bundleName: content.bundleName,
            mode: mode,
            name: content.name,
            tips: content.tips,
            title: content.title,
            winText: content.winText,
            loseText: content.loseText,
            reward: content.reward,
            level: content.level,
            sourceLevel: content.sourceLevel,
            gameAloneBundle: content.gameAloneBundle,
            oldLevel: content.oldLevel,
            hideTitle: content.hideTitle,
            subPower: content.subPower,
            infinityFlag:content.infinityFlag,
            levelNum:content.levelNum,
            levelType:content.levelType
        };
        // console.warn(mode, sceneMode, prams);
        let object = mainRoot.LevelSystem.GetModeLevelInfo(mode);
        let level = this.GetCurrLevel(mode);
        //console.debug(object, "prams.gameAloneBundle", prams.gameAloneBundle);
        if (prams.gameAloneBundle) {
            await new Promise<void>(resolve=>{
                cc.assetManager.loadBundle(prams.gameAloneBundle, (error, bundle)=>{
                    if(error){
                        console.error(error);
                        resolve();
                        return;
                    }
                    resolve();
                });
            });
            await O1HD.getManagers().soundMgr.loadSoundBundle(`level${object[level]['level']}`, prams.gameAloneBundle);
        }
        let levelType:number = content.levelType;
        console.log(levelType,"关卡类型>>>>>>>>>>>")
        await this.loadOneTypeBundle(levelType);
        await O1HD.getManagers().gameMgr.selectMode(sceneMode,isShowLoading);
        let name: string = content.name;
        // this.Log("real", realNum, name);

        services()
            .miniGameSrv.getAppApiInstance()
            .reportAnalytics("Level", {
                loadLevel: `${MODE_NAME_MAP[mode]}:${realNum}`,
            });

        let sceneCom = O1HD.Canvas().getComponent(NormalLevelBase);
        await new Promise<void>((resolve, reject) => {
            if (!name) {
                resolve();
                console.warn("非常规类型", sceneCom == null);
                // return;
            } else {
                const loadPrefabOver = (err, prefab: cc.Prefab) => {
                    if (err) {
                        console.error(err);
                        reject();
                        return;
                    }
                    let gamePlayerLayer: cc.Node =
                        O1HD.Canvas().getChildByName("GamePlayLayer");

                    if (gamePlayerLayer) {
                        let node = cc.instantiate(prefab);
                        node.name = "LevelNode";
                        let com = node.getComponent(NormalLevelBase);
                        // console.warn("?????", com == undefined);
                        com && com.Init(prams);
                        gamePlayerLayer.addChild(node);
                        // node.y-=100;
                        resolve();
                    } else {
                        console.error("没找到游戏对象");
                    }
                }
                if (prams.gameAloneBundle) {
                    mainRoot.GetBundle(prams.gameAloneBundle).load(name, loadPrefabOver);
                } else {
                    mainRoot.GetBundle(bundleName).load(`Level/${name}`, loadPrefabOver);
                }
            }
        });

        managers().soundMgr.playSound('mainSound/inLevel');
        sceneCom && sceneCom.Init(prams);
        mainRoot.UIModel.hideLoading();
        return Promise.resolve();
    }

    /**
     * 加载一种类型的游戏的bundle
     */
    loadOneTypeBundle(type:string | number){
        O1HD.getModules().uiControlModule.showLoading(null,"正在加载关卡资源");
        return new Promise<void>(resolve=>{
            cc.assetManager.loadBundle(this.getBundleNameByType(type),cc.AssetManager.Bundle,(err,bundle:cc.AssetManager.Bundle)=>{
                resolve();
            });
        });
    }

    getOneBundByInstant(bundleName:string){
        return cc.assetManager.getBundle(bundleName);
    }

    getBundleNameByType(type:string | number){
        let bundleName:string = "";
        switch(type){
            case 0:{
                bundleName = "peopleArchery";
                break;
            }
            case 1:{
                bundleName = "decompressionLibrary";
                break;
            }
            case 3:{
                bundleName = "LianXian";
                break;
            }
            case 4:{
                bundleName = "bunchbunchbunch";
                break;
            }
            case 5:{
                bundleName = "goldMiner";
                break;
            }
        }
        return bundleName;
    }

    getOneTypeBundle(type:string | number){
        return cc.assetManager.getBundle(this.getBundleNameByType(type));
    }

}

